import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import os
current_path = os.path.dirname(os.path.abspath(__file__))
tf.keras.backend.clear_session()

inputs = keras.Input(shape=(784,),name='img')
x = layers.Dense(64,activation='relu')(inputs)
x = layers.Dense(64,activation='relu')(x)
outputs = layers.Dense(10,activation='softmax')(x)

model = keras.Model(inputs = inputs,outputs=outputs,name='mnist_model')
model.summary()
keras.utils.plot_model(model, os.path.join(current_path,'my_first_model.png'))
keras.utils.plot_model(model,'my_first_model_with_shape_infp.png',show_shapes=True)

(x_train,y_train),(x_test,y_test) = keras.datasets.mnist.load_data()
x_train = x_train.reshape(60000,784).astype('float32') / 255
x_test = x_test.reshape(10000,784).astype('float32') / 255

model.compile(loss='sparse_categorical_crossentropy',
              optimizer=keras.optimizers.RMSprop(),
              metrics=['accuracy'])

history = model.fit(x_train,y_train,
                    batch_size = 64,
                    epochs=5,
                    validation_split=0.2)

test_scores = model.evaluate(x_test,y_test,verbose=0)
print("Test loss:",test_scores[0])
print("Test accuracy:",test_scores[1])

model.save('path_to_my_model.h5')
del model
# Recreate the exact same model purely from the file:
model = keras.models.load_model('path_to_my_model.h5')

encoder_input = keras.Input(shape=(28,28,1),name='img')
x = layers.Conv2D(16,3,activation='relu')(encoder_input)
x = layers.Conv2D(32,3,activation='relu')(x)
x = layers.MaxPool2D(3)(x)
x = layers.Conv2D(32,3,activation='relu')(x)
x = layers.Conv2D(16,3,activation='relu')(x)
encoder_output = layers.GlobalAveragePooling2D()(x)

encoder = keras.Model(encoder_input,encoder_output,name='encoder')
encoder.summary()

decoder_input = keras.Input(shape=(16,), name='encoded_img')
x = layers.Reshape((4,4,1))(decoder_input)
x = layers.Conv2DTranspose(16,3,activation='relu')(x)
x = layers.Conv2DTranspose(32,3,activation='relu')(x)
x = layers.UpSampling2D(3)(x)
x = layers.Conv2DTranspose(16,3,activation='relu')(x)
decoder_output = layers.Conv2DTranspose(1,3,activation='relu')(x)
decoder = keras.Model(decoder_input, decoder_output, name='decoder')
decoder.summary()

autoencoder = keras.Model(decoder_input,decoder_output,name='autoencoder')
autoencoder.summary()

autoencoder_input = keras.Input(shape=(28,28,1),name='img')
encoded_img = encoder(autoencoder_input)
decoded_img = decoder(encoded_img)
autoencoder = keras.Model(autoencoder_input,decoded_img,name='autoencoder')
autoencoder.summary()


def get_model():
    inputs = keras.Input(shape=(128,))
    outputs = layers.Dense(1,activation='sigmoid')(inputs)
    return  keras.Model(inputs,outputs)

model1 = get_model()
model2 = get_model()
model3 = get_model()

inputs = keras.Input(shape=(128,))
y1 = model1(inputs)
y2 = model2(inputs)
y3 = model3(inputs)
outputs = layers.average([y1,y2,y3])
ensemble_model = keras.Model(inputs=inputs,outputs=outputs)




